/*
package cn.qicaiwang.open.admin.controller.common;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.qicaiwang.crm.common.MessageBodyTypeEnum;
import cn.qicaiwang.crm.common.MessageEventEnum;
import cn.qicaiwang.crm.common.MessageTypeEnum;
import cn.qicaiwang.crm.model.entity.Message;
import cn.qicaiwang.crm.model.entity.MessageBody;
import cn.qicaiwang.open.common.constant.Constants;
import cn.qicaiwang.open.common.entity.LoginUser;
import cn.qicaiwang.open.common.enums.ResultStatusCodeEnum;
import cn.qicaiwang.open.common.exception.BusinessException;
import cn.qicaiwang.open.common.response.ResponseResult;
import cn.qicaiwang.open.common.utils.SecurityUtil;
import cn.qicaiwang.open.common.utils.jwt.JwtTokenUtil;
import cn.qicaiwang.open.system.model.entity.*;
import cn.qicaiwang.open.system.service.*;
import com.alibaba.fastjson.JSON;
import com.xkcoding.justauth.AuthRequestFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("oauth")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WechatLoginController {
    private final AuthRequestFactory factory;
    @Autowired
    private ISystemUserWechatService systemUserWechatService;
    @Autowired
    private ISystemUserService systemUserService;
    @Autowired
    private ISystemRoleService systemRoleService;
    @Autowired
    private ISystemMenuService systemMenuService;
    @Autowired
    private ISystemUnitService systemUnitService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("wechat")
    public void login(HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get("WECHAT_OPEN");
        String authorize = authRequest.authorize(AuthStateUtils.createState());
        response.sendRedirect(authorize);
    }

    @RequestMapping("wechat/callback")
    public void callback(AuthCallback callback, HttpServletRequest request) {
        AuthRequest authRequest = factory.get("WECHAT_OPEN");
        log.info("[callback]: {}", JSON.toJSONString(callback));

        AuthResponse authResponse = authRequest.login(callback);
        log.info("【response】= {}", JSONUtil.toJsonStr(authResponse));

        String wechatOauthType = request.getHeader("WechatOauthType");

        AuthUser authUser = (AuthUser) authResponse.getData();
        String code = callback.getCode();
        String unionId = authUser.getToken().getUnionId();
        SystemUserWechat temp = systemUserWechatService.selectOneByUnionId(unionId);
        if("login".equals(wechatOauthType)) {
            if (temp != null) {
                SystemUser systemUser = systemUserService.getById(temp.getUserId());
                if (systemUser == null) {
                    throw new UsernameNotFoundException("用户不存在");
                }
                if (systemUser.getEnabled() != 1) {
                    throw new DisabledException("用户已禁用");
                }
                LoginUser loginUser = new LoginUser();
                BeanUtils.copyProperties(systemUser, loginUser);

                Set<String> roles = new HashSet<>();
                Set<String> permissions = new HashSet<>();
                if (systemUser.getUserType() == 1) {
                    roles.add("SUPER_ADMIN");
                    permissions.add("*:*:*");
                } else {
                    // 查询角色
                    List<SystemRole> systemRoles = systemRoleService.selectListByUserId(systemUser.getId());
                    roles = systemRoles.stream().map(SystemRole::getRolePerm).collect(Collectors.toSet());
                    // 查询菜单、权限
                    List<SystemMenu> systemMenus = systemMenuService.selectListByUserId(systemUser.getId());
                    permissions = systemMenus.stream().map(SystemMenu::getPerms).collect(Collectors.toSet());
                }
                // 机构
                SystemUnit systemUnits = systemUnitService.getById(systemUser.getUnitId());

                loginUser.setRoles(roles);
                loginUser.setPermissions(permissions);
                loginUser.setUnit(systemUnits);

                String jwt = JwtTokenUtil.generateToken(loginUser);

                redisTemplate.opsForValue().set(Constants.ACCESS_TOKEN_PREFIX + code, jwt, 10, TimeUnit.MINUTES);
            } else {
                throw new UsernameNotFoundException("该微信未绑定系统账号，请先绑定");
            }
        }else if("bind".equals(wechatOauthType)){
            String userId = SecurityUtil.getUserId();
            if(temp != null){
                // TODO
                redisTemplate.opsForValue().set(Constants.WECHAT_BIND_PREFIX + userId, ResultStatusCodeEnum.WECHAT_BINDED.getCode());
                throw new BusinessException("该微信已绑定账号，请先解绑");
            }
            SystemUserWechat systemUserWechat = new SystemUserWechat();
            systemUserWechat.setId(IdUtil.getSnowflakeNextIdStr());
            systemUserWechat.setUnionId(unionId);
            systemUserWechat.setUuid(authUser.getUuid());
            systemUserWechat.setMpOpenId("");
            systemUserWechat.setUsername(authUser.getUsername());
            systemUserWechat.setNickname(authUser.getNickname());
            systemUserWechat.setAvatar(authUser.getAvatar());
            systemUserWechat.setBlog(authUser.getBlog());
            systemUserWechat.setCompany(authUser.getCompany());
            systemUserWechat.setLocation(authUser.getLocation());
            systemUserWechat.setEmail(authUser.getEmail());
            systemUserWechat.setRemark(authUser.getRemark());
            systemUserWechat.setGender(authUser.getGender().getCode());
            systemUserWechat.setSource("WECHAT");
            systemUserWechat.setUserId(userId);

            SystemUser updateUser = new SystemUser();
            updateUser.setId(userId);
            updateUser.setAvatar(authUser.getAvatar());
            systemUserService.bindWechat(updateUser, systemUserWechat);
        }
    }

    @GetMapping("getAccessToken")
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult getAccessToken(String code){
        if(StrUtil.isBlank(code)){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        if(!redisTemplate.hasKey(Constants.ACCESS_TOKEN_PREFIX + code)){
            return ResponseResult.error(ResultStatusCodeEnum.WECHAT_NOT_BIND);
        }
        String accessToken = redisTemplate.opsForValue().get(Constants.ACCESS_TOKEN_PREFIX + code);


        LoginUser loginUser = JwtTokenUtil.getLoginUserFromToken(accessToken);

        MessageBody body = new MessageBody();
        body.setType(MessageBodyTypeEnum.message.name());
        body.setContent(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "登录成功。");

        Message message = Message.builder()
                .id(IdUtil.getSnowflakeNextIdStr())
                .title("小鹿线CRM客户管理系统")
                .event(MessageEventEnum.login.name())
                .msgType(MessageTypeEnum.text.name())
                .fromUserId("-1")
                .toUserId(loginUser.getId())
                .result(loginUser.getUsername())
                .message(body)
                .build();
        // 发送消息
        rabbitTemplate.convertAndSend(Constants.RABBITMQ_DEFAULT_DIRECT_EXCHANGE, Constants.RABBITMQ_DEFAULT_DIRECT_ROUTING, message);

        return ResponseResult.ok(accessToken);
    }
}
*/
